package qj.tool.gae.config;

import java.io.IOException;
import java.io.Writer;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import qj.tool.gae.DB;
import qj.tool.gae.config.ConfigGae.ConfigMeta;
import qj.tool.gae.config.ConfigGae.ConfigMeta.Group;
import qj.tool.gae.db.JsonUtil;
import qj.util.*;
import qj.util.cache.Caches;
import qj.util.funct.F1;
import qj.util.funct.P1;

@SuppressWarnings({"rawtypes"})
public class ConfigServletSupportGae {

	private final ConfigGae configGae;

	public F1<Date,String> formatT = new F1<Date,String>() {public String e(Date d) {
		return String.valueOf(d);
	}};

	public F1<Long,String> formatTimeLength = new F1<Long,String>() {public String e(Long d) {
		return LanguageUtil.translateMillis(d);
	}};

	public ConfigServletSupportGae(ConfigGae configGae) {
		this.configGae = configGae;
	}
	
	public P1<Writer> configPageWriteF() {
		final String configTemplate = FileUtil.readFileToString( "WEB-INF/template/config.html");
		return new P1<Writer>() {public void e(Writer writer) {
			
			
			List<Map> groups = groups();
			VelocityContext context = new VelocityContext();
			context.put("groups", groups);
			context.put("formatT", formatT);
			context.put("formatTimeLength", formatTimeLength);
			context.put("now", new Date());

//			final String configTemplate = FileUtil.readFileToString( "WEB-INF/template/config.html");
			Velocity.evaluate(context, writer, "config.html", configTemplate);
			
		}};
	}

	public void servePost(HttpServletRequest req, HttpServletResponse resp) {
		try {
			String action = req.getParameter("subAction");
			if ("set".equals(action)) {
				String id = req.getParameter("id");
				String value = req.getParameter("value");
				String type = req.getParameter("type");
				
				if ("BigString".equals(type)) {
					type = "String";
				}
				
				DB.save(Config.create(id,value,type));
				
				resp.getWriter().write(JsonUtil.serialize(Cols.map("status","ok")));
			} else if ("refresh".equals(action)) {
				configGae.refresh();
				resp.getWriter().write(JsonUtil.serialize(Cols.map("status","ok")));
			} else if ("refresh1".equals(action)) {
				String id = req.getParameter("id");
				configGae.refresh(id);
				resp.getWriter().write(JsonUtil.serialize(Cols.map("status","ok", "effectiveValue", configGae.get(id))));
			} else if ("clear".equals(action)) {
				configGae.clear(req.getParameter("id"));
				resp.getWriter().write(JsonUtil.serialize(Cols.map("status","ok")));
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	private List<Map> groups() {
		LinkedList<Map> allGroups = new LinkedList<Map>();
		for (Group group : configGae.configMetaGroups) {
			List<Map> configs = new LinkedList<Map>();
			for (ConfigMeta configMeta : group.configMetas) {
				
				if ("system".equals(configMeta.storeType)) {
					continue;
				}

//				Config config = DB.getName(configMeta.name, Config.class);
//				ge

				Object effectiveValue = configGae.get(configMeta.name);
				Date nextCheck = configMeta.refreshRate==null || configMeta.refreshRate==0 ? null : new Date(Caches.nextCheck(configMeta.refreshRate));
				configs.add(Cols.map(
						"id", configMeta.name,
						"type", configMeta.type,
//						"refreshRate", refreshRate,
						"effectiveValue",effectiveValue==null ? "" : effectiveValue,
						"nextCheck", nextCheck
//						,
//						"stringValue", config==null ? "" : config.getStringValue()
						));
			}
			allGroups.add(Cols.map(
					"name", group.name==null ? "Misc" : group.name,
					"configs", configs
					));
		}
		
		return allGroups;
	}
}
